package com.web.wechat.global.controller;

import com.blue.core.dict.HttpMethod;
import com.blue.http.annotation.Http;
import com.blue.http.config.ErrorConfig;
import com.blue.http.message.HttpRequest;
import com.blue.http.message.View;
import com.blue.http.message.ViewBuilder;
import com.blue.wechat.invoke.WechatInvoker;
import com.web.base.user.facade.UserFacade;
import com.web.base.user.message.UserRequest;
import com.web.base.user.message.UserResponse;
import com.web.base.wechat.facade.WechatFacade;
import com.web.base.wechat.facade.WechatInvokerFacade;
import com.web.base.wechat.message.UserInfoResponse;
import com.web.base.wechat.message.WechatResponse;
import com.web.core.cache.ConfigCache;
import com.web.core.util.Const;
import com.web.wechat.global.model.User;
import com.web.wechat.global.model.UserWechat;
import com.web.wechat.global.util.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.MessageFormat;

@Controller
@Http(url = "/app/oauth")
public class OAuthController
{
	private static Logger logger = LoggerFactory.getLogger(OAuthController.class);
	
	@Resource
	private ConfigCache configCache;
	@Resource
	private HttpContext httpContext;
	@Autowired
	private UserFacade userFacade;
	@Autowired
	private WechatFacade wechatFacade;
	@Autowired
	private WechatInvokerFacade wechatInvokerFacade;

	private ErrorConfig errorConfig = ErrorConfig.getInstance();
	
	public OAuthController()
	{
	}
	
	@Http(url = "/code", method = HttpMethod.GET)
	public View code(HttpRequest request) throws IOException
	{
		String code = configCache.getValue(Const.WECHAT_CODE);
		if (code == null || code.isEmpty())
			throw errorConfig.getException(ErrorConfig.LOGIN);

		WechatResponse wechat = wechatFacade.getByCode(code);
		if (wechat == null)
			throw errorConfig.getException(ErrorConfig.LOGIN);
		
		String uri = URLEncoder.encode(configCache.getValue("wechat_path") + "/app/oauth/token", "UTF-8");
		String url = MessageFormat.format(WechatInvoker.OAUTH_REDIRECT.getUrl(), wechat.getAppId(), uri, code);
		logger.info(url);
		return View.createBuilder().setLocation(url).build();
	}
	
	@Http(url = "/token", method = HttpMethod.GET)
	public View token(HttpRequest request) throws IOException
	{
		String code = request.getQueryString("code");
		String state = request.getQueryString("state");
		logger.info("code: {} === state: {}", code, state);
		if (code == null || code.isEmpty())
			throw errorConfig.getException(ErrorConfig.LOGIN);
		
		UserInfoResponse userInfo = wechatInvokerFacade.getOAuthUserInfo(code, state);
		if (userInfo == null)
			throw errorConfig.getException(ErrorConfig.LOGIN);

		WechatResponse wechat = wechatFacade.getByCode(state);
		logger.info("用户昵称：{}，openid：{}，unionid：{}", userInfo.getNickname(), userInfo.getOpenid(), userInfo.getUnionid());
		
		String url = MessageFormat.format("{0}/app/oauth/success?wxOpenId={1}&wxUnionId={2}&wechatId={3}&wechatCode={4}",
				configCache.getValue("wechat_path"), userInfo.getOpenid(),
				userInfo.getUnionid() == null ? "" : userInfo.getUnionid(), wechat.getId(), state);
		logger.info(url);
		return View.createBuilder().setLocation(url).build();
	}
	
	@Http(url = "/success", method = HttpMethod.GET)
	public View susccess(HttpRequest request) throws IOException
	{
		UserWechat uw = request.getQueryObject(UserWechat.class);
		if (uw.getWxOpenId() == null || uw.getWxOpenId().isEmpty())
			throw errorConfig.getException(ErrorConfig.LOGIN);

		UserRequest userRequest = new UserRequest();
		userRequest.setWxOpenId(uw.getWxOpenId());
		userRequest.setWxUnionId(uw.getWxUnionId());
		userRequest.setWechatId(uw.getWechatId());
		userRequest.setIp(request.getIp());
		UserResponse userResponse = userFacade.loginWechat(userRequest);
		ViewBuilder builder = View.createBuilder();
		if (userResponse == null) // 登录失败
		{
			logger.info("登录失败");
			httpContext.setUserWechat(request, uw);
			String url = configCache.getValue(Const.WECHAT_PATH) + "/app/login";
			return builder.setLocation(url).build();
		}

		logger.info("登录成功");
		httpContext.setUser(request, User.toUser(userResponse));
		String url = httpContext.getLastUrl(request);
		logger.info("跳转：{}", url);
		if (url == null || url.isEmpty())
		{
			url = configCache.getValue(Const.WECHAT_PATH) + "/index" + Const.EXT;
		}
		return builder.setLocation(url).build();
	}
	
}
